#pragma once

#include <cassert>

#define IMPL_SINGLETON(TYPE) TYPE *xs::Singleton<TYPE>::m_instance = 0
#define SINGLETON(TYPE) class TYPE: public xs::Singleton<TYPE>

template <typename T> 
class Singleton
{
public:
    Singleton()
    {
        assert(!m_instance);

        int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
        m_instance = (T*)((int)this + offset);
    }

    ~Singleton()
    {
        assert(m_instance);
        m_instance = 0;
    }   

    static T& get_instance()
    {
        assert(m_instance);
        return *m_instance;
    }

    static T* get_instance_pointer()
    {
        assert(m_instance);
        return m_instance;
    }
protected:
    static T *m_instance;
};